package com.hxwm.hwdbtool.service;

import com.hxwm.hwdbtool.entity.dbconnect.*;
import com.hxwm.hwdbtool.util.DataSourceMetaDataUtil;
import com.hxwm.hwdbtool.util.HwUtil;
import javafx.scene.control.TreeItem;
import org.apache.log4j.Logger;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: hwdbtool
 * @ClassName DataBaseNavService
 * @description:
 * @author: hxwm
 * @create: 2024-06-16 17:14
 * @Version 1.0
 **/
public class DataBaseNavService {
    private static final String DATA_DIRECTORY = "data";
    private static final String DB_CONFIG_FILE = "dbconfig.txt";
    private static Map<String,HwConnection> hwConnectionListMap;//数据源map
    private static DataBaseNavService dataBaseNavService;
    public static DataBaseNavService getInstance() {
        if(dataBaseNavService == null){
            dataBaseNavService = new DataBaseNavService();
            hwConnectionListMap = new HashMap<>();
        }
        return dataBaseNavService;
    }

    /**
     * 加载数据库配置信息
     * @return
     */
    public List<TreeItem<String>> loadUserDatabaseInfoConfig(){
        //获取当前目录
        List<TreeItem<String>> databaseConfigList = new ArrayList<>();
        String currentDirectory = System.getProperty("user.dir");
        File dataConfigFile  = new File(currentDirectory.substring(0,currentDirectory.lastIndexOf(File.separator))+ File.separator + DATA_DIRECTORY, DB_CONFIG_FILE);
        if (dataConfigFile.exists()) {
            try(BufferedReader reader = new BufferedReader(new FileReader(dataConfigFile))){
                String line = "";
                while (!HwUtil.isNullOrEmpty(line = reader.readLine())) {
                    String[] split = line.split("\\,");
                    HwDateSource hwDateSource = new HwDateSource(split[0], split[1], split[2]);
                    databaseConfigList.add(getDatabaseInfoList(hwDateSource));
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return databaseConfigList;
    }

    /**
     * 导航栏列表拼接
     * @param hwDateSource
     * @return
     */
    public TreeItem<String> getDatabaseInfoList(HwDateSource hwDateSource){
        HwConnection databaseConnectInfo = DataSourceMetaDataUtil.getDatabaseConnectInfo(hwDateSource);
        TreeItem<String> databaseInfoRoot = new TreeItem<>(databaseConnectInfo.getConnectionName());
        hwConnectionListMap.put(databaseConnectInfo.getConnectionName(),databaseConnectInfo);
        //==========================================================================================
        //添加数据库列表
        List<HwDatabase> databaseList = databaseConnectInfo.getDatabaseList();

        TreeItem<String> databases = new TreeItem<>("数据库");
        for (HwDatabase hwDatabase : databaseList) {
            List<HwTable> tableList = hwDatabase.getTableList();
            List<HwView> viewList = hwDatabase.getViewList();
            if(!HwUtil.isNullOrEmpty(tableList)){
                TreeItem<String> databaseItem = new TreeItem<>(hwDatabase.getDatabaseName());
                //添加表列表
                TreeItem<String> tables = new TreeItem<>("表");
                for (HwTable hwTable : tableList) {
                    TreeItem<String> tableItem = new TreeItem<>(hwTable.getTableName());

                    List<HwColumn> columnList = hwTable.getColumnList();
                    //添加表字段列表
                    TreeItem<String> columns = new TreeItem<>("列");
                    TreeItem<String> primaryKey = new TreeItem<>("约束");
                    TreeItem<String> foreignKey = new TreeItem<>("外键");
                    TreeItem<String> quote = new TreeItem<>("引用");
                    TreeItem<String> trigger = new TreeItem<>("触发器");
                    TreeItem<String> index = new TreeItem<>("索引");
                    for (HwColumn hwColumn : columnList) {
                        TreeItem<String> columnItem = new TreeItem<>(hwColumn.getColumnName());
                        columns.getChildren().add(columnItem);
                    }
                    tableItem.getChildren().add(columns);
                    tableItem.getChildren().add(primaryKey);
                    tableItem.getChildren().add(foreignKey);
                    tableItem.getChildren().add(quote);
                    tableItem.getChildren().add(trigger);
                    tableItem.getChildren().add(index);
                    tables.getChildren().add(tableItem);
                }
                //添加视图
                TreeItem<String> views = new TreeItem<>("视图");
                for (HwView hwView : viewList) {
                    TreeItem<String> viewItem = new TreeItem<>(hwView.getViewName());

                    List<HwColumn> columnList = hwView.getColumnList();

                    TreeItem<String> columns = new TreeItem<>("列");
                    for (HwColumn hwColumn : columnList) {
                        TreeItem<String> columnItem = new TreeItem<>(hwColumn.getColumnName());
                        columns.getChildren().add(columnItem);
                    }
                    viewItem.getChildren().add(columns);
                    views.getChildren().add(viewItem);
                }
                //添加到数据库
                databaseItem.getChildren().add(tables);
                databaseItem.getChildren().add(views);
                databases.getChildren().add(databaseItem);
            }
        }
        TreeItem<String> userNames = new TreeItem<>("用户");
        List<HwDBUser> userList = databaseConnectInfo.getUserList();
            for (HwDBUser hwDBUser : userList) {
            TreeItem<String> userItem = new TreeItem<>(hwDBUser.getUserName());
            List<HwUserRight> userRightList = hwDBUser.getUserRightList();
            for (HwUserRight hwUserRight : userRightList) {
                TreeItem<String> userRightItem = new TreeItem<>(hwUserRight.getUserRightName());
                userItem.getChildren().add(userRightItem);
            }
            userNames.getChildren().add(userItem);
        }
        databaseInfoRoot.getChildren().add(databases);
        databaseInfoRoot.getChildren().add(userNames);

        return databaseInfoRoot;
    }

    /**
     * 将数据库配置存储到配置文件
     * @param hwDateSource
     * @param logger
     */
    public void saveDatabaseConfig(HwDateSource hwDateSource, Logger logger) {
        //获取当前目录
        String currentDirectory = System.getProperty("user.dir");
        File dataDirectory  = new File(currentDirectory.substring(0,currentDirectory.lastIndexOf(File.separator))+ File.separator + DATA_DIRECTORY);
        File dataConfigFile = new File(dataDirectory,DB_CONFIG_FILE);
        logger.info("当前目录：" + currentDirectory);
        if (!dataDirectory.exists()) {
            dataDirectory.mkdirs();
            logger.info("文件不存，创建文件:" + dataConfigFile.getAbsolutePath());
        }
        if(!dataConfigFile.exists()){
            try {
                dataConfigFile.createNewFile();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        Boolean isExistsConfig = false;
        try(BufferedReader reader = new BufferedReader(new FileReader(dataConfigFile))){
            String line = "";
            while (!HwUtil.isNullOrEmpty(line = reader.readLine())) {
                //判断配置是否已经存在
                if(line.startsWith(hwDateSource.getDbUrl())){
                    logger.info("配置已存在!");
                    isExistsConfig = true;
                    break;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        if(!isExistsConfig) {
            //写入配置信息
            try (PrintWriter writer = new PrintWriter(new FileWriter(dataConfigFile, true))) {
                writer.println(hwDateSource.getDbUrl() + "," + hwDateSource.getDbUser() + "," + hwDateSource.getDbPassword());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 移除配置
     * @param url
     */
    private void removeDatabaseConnection(String url) {
        try {
            File configFile = new File(DATA_DIRECTORY, DB_CONFIG_FILE);
            List<String> lines = new ArrayList<>();
            BufferedReader reader = new BufferedReader(new FileReader(configFile));
            String line;
            while ((line = reader.readLine()) != null) {
                if (!line.startsWith(url)) {
                    lines.add(line);
                }
            }
            reader.close();
            PrintWriter writer = new PrintWriter(new FileWriter(configFile));
            for (String l : lines) {
                writer.println(l);
            }
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Map<String, HwConnection> getHwConnectionListMap() {
        return hwConnectionListMap;
    }

    public static void setHwConnectionListMap(Map<String, HwConnection> hwConnectionListMap) {
        DataBaseNavService.hwConnectionListMap = hwConnectionListMap;
    }
}